from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *
from math import *
import Ui_jurnalEdit
import master.utility as utility

class JurnalEdit(QDialog, Ui_jurnalEdit.Ui_jurnalEditDlg):
  StyleSheet = """
QLineEdit[mandatory="true"] {
    background-color: rgb(255, 255, 127);
    color: darkblue;
}
"""
  def __init__(self, dbConn, tipe, dataGlob, parent=None):
        super(JurnalEdit, self).__init__(parent)
        self.setupUi(self)
        self.db = dbConn
        self.tipe = tipe
        self.dataGlob = dataGlob
        self.util = utility.Utility(self.db)
        
        self.mastModel = QSqlTableModel(self)
        self.mastModel.setTable("trans_jurnal")
        self.mastModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        
        self.detModel = QSqlRelationalTableModel(self)
        self.detModel.setTable("trans_jurnal_detail")
        self.detModel.setRelation(0, QSqlRelation("v_master_kode_perkiraan", "kode_perkiraan", "nama"))
        self.detModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.detModel.setFilter("no_jurnal = '"+self.tipe+"'")
        self.detModel.setHeaderData(0, Qt.Horizontal, QVariant("COA"))
        self.detModel.setHeaderData(2, Qt.Horizontal, QVariant("Debet (Rp)"))
        self.detModel.setHeaderData(3, Qt.Horizontal, QVariant("Credit (Rp)"))
        self.connect(self.detModel, SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.hitungTotal)
        self.detModel.select()
        
        self.detail_tbv.setModel(self.detModel)
        self.detail_tbv.setItemDelegate(DetailDelegate(self))
        self.detail_tbv.setSelectionMode(QTableView.SingleSelection)
        self.detail_tbv.setSelectionBehavior(QTableView.SelectRows)
        self.detail_tbv.setColumnHidden(1, True)
        self.detail_tbv.setColumnHidden(4, True)
        self.detail_tbv.setColumnWidth(0, 200)
        
        self.tipeModel = QSqlTableModel(self)
        self.tipeModel.setTable("master_jurnal_type")
        self.tipeModel.select()
        self.tipe_cmb.setModel(self.tipeModel)
        self.tipe_cmb.setModelColumn(0)
        self.tipe_cmb.setCurrentIndex(0)
        
#        self.idModel = QSqlTableModel(self)
#        self.idModel.setTable("master_nodok")
#        self.idModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        
        self.urut = 0
        if self.tipe != "add":
            query = QSqlQuery(self.db)
            query.exec_("select max(urut) from trans_jurnal_detail where no_jurnal = '"+self.tipe+"'")
            while query.next():
                self.urut = query.value(0).toInt()[0]
                
        self.initData()
        
        self.lineedits = (self.desc_le, self.ref_le)
        for lineEdit in self.lineedits:
            lineEdit.setProperty("mandatory", QVariant(True))
        self.setStyleSheet(JurnalEdit.StyleSheet)

  @pyqtSignature("")
  def on_save_pb_clicked(self):
      if self.no_le.text() == "":
          if self.tambahData():
              self.close()
          else:
              QMessageBox.warning(self, "Journal","Can't add new data.")
      else:
          if self.updateData():
              self.close()
          else:
              QMessageBox.warning(self, "Journal","Can't update data.")

  @pyqtSignature("")
  def on_cancel_pb_clicked(self):
      self.close()

  @pyqtSignature("")
  def on_add_pb_clicked(self):
      self.urut += 1
      if self.no_le.text() == "":
          if not self.tambahData():
              QMessageBox.warning(self, "Journal","Can't add new data.")
              return
          self.detModel.setFilter("no_jurnal = '"+self.no_le.text()+"'")
          self.detModel.select()
      QSqlDatabase.database().transaction()
      row = self.detModel.rowCount()      
      self.detModel.insertRow(row)
      self.detModel.setData(self.detModel.index(row, 1), QVariant(self.no_le.text()))
      self.detModel.setData(self.detModel.index(row, 4), QVariant(self.urut))
#      self.detModel.submitAll()
      QSqlDatabase.database().commit()
      index = self.detModel.index(row, 0)
      self.detail_tbv.setCurrentIndex(index)
      self.detail_tbv.edit(index)

  @pyqtSignature("")
  def on_del_pb_clicked(self):
      index = self.detail_tbv.currentIndex()
      if not index.isValid():
          return
      self.detModel.removeRow(index.row())
      self.detModel.submitAll()
      
  def tambahData(self):
      if not self.validasi():          
          return
      idBaru = self.idBaru()
      self.no_le.setText(idBaru)
      hari = self.util.getServerToday()
      self.auditTime_dte.setDateTime(hari)
      tgl = hari.date().toString("yyyy-MM-dd")
      self.mastModel.setFilter("tgl_jurnal = '"+tgl+"'")
      self.mastModel.select()     
      QSqlDatabase.database().transaction()
      if not self.mastModel.insertRow(0):
          return
      self.mastModel.setData(self.mastModel.index(0, 0), QVariant(self.tgl_de.date()))
      self.mastModel.setData(self.mastModel.index(0, 1), QVariant(self.no_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 2), QVariant(self.desc_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 3), QVariant(self.auditUser_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 12), QVariant(hari))
      if not self.mastModel.submitAll():
          return
      if not QSqlDatabase.database().commit():
          return
      self.tipe = idBaru
      return True
      
  def updateData(self):
      self.detModel.submitAll()
#      self.hitungTotal()
      if not self.validasi():
          return
      self.mastModel.setFilter("no_jurnal = '"+self.tipe+"'")
      self.mastModel.select()
      QSqlDatabase.database().transaction()
      self.mastModel.setData(self.mastModel.index(0, 0), QVariant(self.tgl_de.date()))
      self.mastModel.setData(self.mastModel.index(0, 1), QVariant(self.no_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 2), QVariant(self.desc_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 4), QVariant(self.bank_de.date()))
      self.mastModel.setData(self.mastModel.index(0, 5), QVariant(self.due_de.date()))
      self.mastModel.setData(self.mastModel.index(0, 6), QVariant(self.ref_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 7), QVariant(self.unit_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 9), QVariant(self.refj_le.text()))
      self.per_le.setText(self.tgl_de.date().toString("yyyy-MM"))
      self.mastModel.setData(self.mastModel.index(0, 10), QVariant(self.per_le.text()))
      self.mastModel.setData(self.mastModel.index(0, 11), QVariant(self.tipe_cmb.currentText()))
      if not self.mastModel.submitAll():
          return
      if not QSqlDatabase.database().commit():
          return
      return True
      
  def initData(self):
      hari = self.util.getServerToday()
      self.tgl_de.setDate(hari.date())
      self.auditTime_dte.setDateTime(hari)
      self.auditUser_le.setText(self.dataGlob["nama"])
      if self.tipe != "add":
          query = QSqlQuery(self.db)          
          qStr = "select m.tgl_jurnal, m.no_jurnal, m.desk_jurnal, m.no_ref, m.kode_client, m.cab, m.jatuh_tempo, m.kode_user, m.tgl_entry,  m.kode_buyer, m.kode_periode, m.jurnal_type, m.audit_time from trans_jurnal m where m.no_jurnal = '"+self.tipe+"'"
          query.exec_(qStr)
          query.next()
          self.tgl_de.setDate(query.value(0).toDate())
          self.no_le.setText(unicode(query.value(1).toString()))
          self.desc_le.setText(unicode(query.value(2).toString()))
          self.ref_le.setText(unicode(query.value(3).toString()))
          self.unit_le.setText(unicode(query.value(4).toString()))
          self.refj_le.setText(unicode(query.value(5).toString()))
          self.due_de.setDate(query.value(6).toDate())
          self.auditUser_le.setText(unicode(query.value(7).toString()))
          self.bank_de.setDate(query.value(8).toDate())
          self.per_le.setText(unicode(query.value(10).toString()))
          brs = self.tipeModel.match(self.tipeModel.index(0, 0), 0, query.value(11),1, Qt.MatchWrap )
          if len(brs) > 0:
              self.tipe_cmb.setCurrentIndex(brs[0].row())
          self.auditTime_dte.setDateTime(query.value(12).toDateTime())
          
  def idBaru(self):
#      noAkhir = 0
#      query = QSqlQuery(self.db)
      kode = "JV"
      per = self.util.getServerToday().date().toString("MMyyyy")
      noAkhir = self.util.getNewId(kode, per, "trans jurnal")
#      self.idModel.setFilter("kode_dok = '"+kode+"' and periode = '"+per+"'")
#      self.idModel.select()      
#      class DatabaseError(Exception): pass
#      rback = False
#      try:
#          if not QSqlDatabase.database().transaction():
#              raise DatabaseError
#          rback = True
#          if self.idModel.rowCount() == 1:
#              record = self.idModel.record(0)
#              noAkhir = record.value(2).toInt()[0]
#              noAkhir += 1
#              self.idModel.setData(self.idModel.index(0, 2), QVariant(noAkhir))
#          else:
#              self.idModel.insertRow(0)
#              self.idModel.setData(self.idModel.index(0, 0), QVariant(kode))
#              self.idModel.setData(self.idModel.index(0, 1), QVariant(per))
#              self.idModel.setData(self.idModel.index(0, 2), QVariant("1"))
#              self.idModel.setData(self.idModel.index(0, 3), QVariant("trans jurnal"))
#              noAkhir = 1
#          self.idModel.submitAll()
#          if not QSqlDatabase.database().commit():
#            raise DatabaseError
#          rback = False
#      finally:
#          if rback:
#              if not QSqlDatabase.database().rollback():
#                  raise DatabaseError
      id = kode+"-"+per+"-"+"0"*(6 - len(str(noAkhir)))+str(noAkhir)
      return id
            
  def hitungTotal(self):
      totBrs = self.detModel.rowCount()
      jum = 0
      for i in range(totBrs):
          record = self.detModel.record(i)
          jum += record.value(2).toDouble()[0]
      
  def validasi(self):
      valid = True
      for lineEdit in self.lineedits:
           if lineEdit.text().isEmpty():
               QMessageBox.warning(self, "Journal","Data not valid / Empty column.")
               return False
      return valid


class DetailDelegate(QSqlRelationalDelegate):
    def __init__(self, parent=None):
        super(DetailDelegate, self).__init__(parent)
        self.coaModel = QSqlQueryModel(self)
        self.coaModel.setQuery("select kode_perkiraan, nama from master_kode_perkiraan where detail = 'Y' order by kode_perkiraan")
        
    def paint(self, painter, option, index):
        myoption = QStyleOptionViewItem(option)
        if index.column() == 2 or index.column() == 3:
            myoption.displayAlignment |= Qt.AlignRight|Qt.AlignVCenter
        QSqlRelationalDelegate.paint(self, painter, myoption, index)
        
#    def createEditor(self, parent, option, index):
#        if index.column() == 0:
#            editor = QComboBox(parent)
#            editor.setModel(self.coaModel)
#            editor.setModelColumn(1)
#            editor.setCurrentIndex(0)                    
#            return editor
#        else:
#            return QSqlRelationalDelegate.createEditor(self, parent, option, index)
#            
#    def setEditorData(self, editor, index):
#        if index.column() == 0:
#            text = index.model().data(index, Qt.DisplayRole).toString()
#            brs = editor.match(index, 0, text, 1, Qt.MatchWrap )
#            editor.setCurrentIndex(brs[0].row())
#        else:
#            QSqlRelationalDelegate.setEditorData(self, editor, index)
#            
#    def setModelData(self, editor, model, index):
#        if index.column() == 0:
#            model.setData(index, QVariant(editor.currentIndex()))
#        else:
#            QSqlRelationalDelegate.setModelData(self, editor, model, index)
            
if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = JurnalEdit()
    form.show()
    app.exec_()
